package com.kara.woodAgent.agent.tool;

import cn.hutool.core.util.StrUtil;
import com.kara.woodAgent.agent.model.ModelProvider;
import com.kara.woodAgent.agent.tool.provider.Tools;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.data.message.SystemMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.chat.response.ChatResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

/**
 * @author tzy
 * @version 1.0
 * @project wood_agent
 * @description
 * @date 2025/6/11 13:39:02
 */
@Tools(groups = "system")
@Component
public class SystemTools {


    @Tool(name = "exit", value = "完成所有任务之后，调用这个工具通知用户已完成所有子任务完成")
    public String exit(@P("退出原因") String text, @P("退出状态，如果执行成功退出为success,失败退出为fail") String status) {
        return "退出原因：" + text + status;
    }


    @Tool(name = "interrupt", value = "执行过程中,如果需要和用户沟通,来补全信息,请调用这个工具")
    public String interrupt(@P("和用户沟通的消息,会直接展示给用户,需要补全的信息") String message) {
        return "消息：" + message;
    }


    @Tool(name = "getOsInfo", value = "获取当前操作系统的信息，包括操作系统名称、版本和架构")
    public String getOsInfo() {
        String osName = System.getProperty("os.name");
        String osVersion = System.getProperty("os.version");
        String osArch = System.getProperty("os.arch");
        return "操作系统名称: " + osName + ", 版本: " + osVersion + ", 架构: " + osArch;
    }


    @Autowired
    private ModelProvider modelProvider;

    @Tool(name = "execute_command", value = "执行指定的命令行命令，并返回命令执行结果。 注意:该工具不会保留执行状态,所以不能连续执行多个命令,多个命令请合并为一个执行")
    public String executeCommand(
            @P("要执行的命令行命令") String command,
            @P("当前操作系统，如 'windows', 'linux', 'macos' 等") String os,
            @P("当前用户所在的目录") String directory
    ) {

        StringBuilder output = new StringBuilder();
        java.io.File dir = new java.io.File(directory);
        if (!dir.exists() || !dir.isDirectory()) {
            output.append("指定的目录不存在或不是一个有效的目录: ").append(directory);
            return output.toString();
        }
        Process process;
        try {
            ProcessBuilder processBuilder;

            // 根据不同操作系统构建完整命令
            if (os.equalsIgnoreCase("windows")) {
                String fullCommand = "cd /d " + directory + " && " + command;
                processBuilder = new ProcessBuilder("cmd", "/c", fullCommand);
            } else if (os.equalsIgnoreCase("linux") || os.equalsIgnoreCase("macos")) {
                String fullCommand = "cd  " + directory + " && " + command;
                processBuilder = new ProcessBuilder("/bin/bash", "-c", fullCommand);
            } else {
                // 默认使用原命令
                processBuilder = new ProcessBuilder("cd", directory, "&&", command);
            }


            // 执行命令
            process = processBuilder.start();

            String charset = os.equalsIgnoreCase("windows") ? "GBK" : "UTF-8";
            // 获取命令执行结果的输入流
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), charset));
            String line;
            // 读取命令执行结果
            while ((line = reader.readLine()) != null) {
                output.append(line).append("\n");
                System.out.print(line + "\n");
            }
            // 等待命令执行完成
            int exitCode = process.waitFor();
            if (exitCode != 0) {
                // 若命令执行失败，读取错误信息
                BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), charset));
                String errorLine;
                while ((errorLine = errorReader.readLine()) != null) {
                    output.append("错误信息: ").append(errorLine).append("\n");
                    System.out.print(errorLine + "\n");
                }
            }
        } catch (IOException | InterruptedException e) {
            // 处理异常
            output.append("执行命令时发生错误: ").append(e.getMessage());
        }
        String string = output.toString();
        if (StrUtil.isBlank(string)) {
            string = "执行成功";
        }

        //过长就去总结内容
        if (string.length() > 4000) {
            //生成总结
            string = summary(string);
        }
        return string;
    }

    private String summary(String string) {


        ChatLanguageModel chatModel = modelProvider.getChatModel("summary");

        SystemMessage systemMessage = SystemMessage.from("""
                #### 职责
                你是 工具调用后,对返回结果进行总结的助手,工具调用产生的结果可能会很长,直接使用会对其他流程造成影响,所以我需要你帮我把结果总结一下,
                返回简单,明确,直观的内容,共其他节点使用
                #### 要求
                1. 你只对内容进行总结,不进行任何解释,不要返回任何无关的内容
                2. 你总结的结果要和输入的内容所表达的信息一致
                3. 你要提取出输入内容的主要信息,并且在返回中有所体现
                """);

        UserMessage userMessage = UserMessage.from("你要总结的内容是:  " + string);
        ChatResponse response = chatModel.chat(List.of(systemMessage, userMessage));
        return response.aiMessage().text();
    }

}
